package com.ev.k3cloudBusiness.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ev.asl.constant.AslConstant;
import com.ev.common.enums.AuditStatusDict;
import com.ev.custom.dao.DictionaryDao;
import com.ev.custom.dao.MaterielDao;
import com.ev.custom.dao.MaterielTypeDao;
import com.ev.custom.domain.DictionaryDO;
import com.ev.custom.domain.MaterielDO;
import com.ev.custom.domain.MaterielTypeDO;
import com.ev.custom.service.MaterielService;
import com.ev.framework.utils.R;
import com.ev.framework.utils.ShiroUtils;
import com.ev.k3cloud.service.K3CloudService;
import com.ev.k3cloud.service.kingdeeMiddlewareService;
import com.ev.k3cloudBusiness.service.K3MaterialSynService;
import com.ev.k3cloudBusiness.vo.K3DeeSyncVO;
import com.ev.k3cloudBusiness.vo.K3MaterialResultsVo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class K3MaterialSynServiceImpl implements K3MaterialSynService {
    private static final String MATERIEL_TYPE = "material_type";
    private static final String UNIT_TYPE = "uom_type";
    private static final Long UNIT_TYPE_ID = 1L;
    private static final Long MATERIEL_TYPE_ID = 3L;
    @Autowired
    MaterielService materielService;
    @Autowired
    K3CloudService k3CloudService;
    @Autowired
    private DictionaryDao dictionaryDao;
    @Autowired
    private MaterielTypeDao materielTypeDao;
    @Autowired
    private kingdeeMiddlewareService kingdeeMiddlewareService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R MaterialSyn() {
        //查询芯软云物料
        List<MaterielDO> materielDOList=materielService.listForAll();
        //调用K3Cloud物料单据查询接口查询启用的物料

        String materialResult=kingdeeMiddlewareService.MaterielAll();

        K3DeeSyncVO<List<K3MaterialResultsVo>> kingdeeSyncVO = new Gson().fromJson(materialResult,new TypeToken<K3DeeSyncVO<List<K3MaterialResultsVo>>>(){}.getType());

        if(!AslConstant.ZERO.equals(kingdeeSyncVO.getCode()))
        {
            log.info(kingdeeSyncVO.getMsg());
            return  R.error(kingdeeSyncVO.getMsg());
        }

        List<K3MaterialResultsVo> materialResultsVoList=kingdeeSyncVO.getData();

        if(materialResultsVoList.size() > 0)
        {
            long okAudit = AuditStatusDict.OK_AUDIT.getId();
            Long userId = ShiroUtils.getUserId();
            Map<String,Object> param = Maps.newHashMap();
            // 获取本地所有的物料属性、单位、物料类型
            List<DictionaryDO> localAttributeList = dictionaryDao.listByType(MATERIEL_TYPE);
            List<DictionaryDO> localUnitList = dictionaryDao.listByType(UNIT_TYPE);
            List<MaterielTypeDO> localMaterielTypeDOS = materielTypeDao.list(param);
            this.handle(materialResultsVoList,localAttributeList,localUnitList,localMaterielTypeDOS);
            Map<String, Long> localAttributeMap = localAttributeList.stream().distinct().collect(Collectors.toMap(DictionaryDO::getName, DictionaryDO::getId, (v1, v2) -> v1));
            Map<String, Long> localUnitMap = localUnitList.stream().distinct().collect(Collectors.toMap(DictionaryDO::getName, DictionaryDO::getId, (v1, v2) -> v1));
            Map<String, Long> localMaterielTypeMap = localMaterielTypeDOS.stream().distinct().collect(Collectors.toMap(MaterielTypeDO::getName, MaterielTypeDO::getId, (v1, v2) -> v1));
            // 本地物料代码
            List<Long> localIdList = materielDOList.stream().map(MaterielDO::getId).collect(Collectors.toList());
            // K3Cloud物料代码
            List<Long> remoteIdList = materialResultsVoList.stream().map(K3MaterialResultsVo::getId).collect(Collectors.toList());
            // 删除的 k3无，本地有
            List<Long> deleteIdList = localIdList.stream().filter(e -> !remoteIdList.contains(e)).collect(Collectors.toList());
            // 修改的（本地库有的，远端库有的）
            List<Long> updateIdList = remoteIdList.stream().filter(localIdList::contains).collect(Collectors.toList());
            // 新增的（本地库无的，远端库有的）
            remoteIdList.removeAll(updateIdList);
            if(deleteIdList.size()>0)
            {
//            批量删除
                List<MaterielDO> materielDOS=materielDOList.stream().filter(e->deleteIdList.contains(e.getId())).collect(Collectors.toList());
                for (MaterielDO material:materielDOS
                ) {
                    material.setDelFlag(1);
                    material.setUseStatus(0);
                }
                materielService.batchUpdate(materielDOS);
                log.info("批量删除");
            }
            if(updateIdList.size()>0)
            {
//           批量更新
                List<K3MaterialResultsVo> materialResultsList = materialResultsVoList.stream().filter(e -> updateIdList.contains(e.getId())).collect(Collectors.toList());
                List<MaterielDO> materielDOListUpdate=materielDOList.stream().filter(e->updateIdList.contains(e.getId())).collect(Collectors.toList());
                K3MaterialResultsVo materialResults;
                for (MaterielDO materialdo:materielDOListUpdate
                ) {
                    materialResults=materialResultsList.stream().filter(e->(materialdo.getId().equals(e.getId()))).collect(Collectors.toList()).get(0);
                    //物料名称
                    materialdo.setName(materialResults.getName());
                    //物料代码
                    materialdo.setSerialNo(materialResults.getNumber());
                    materialdo.setNetWeight(new BigDecimal(materialResults.getWeight()));

                    //体积
                    materialdo.setVolume(BigDecimal.valueOf(materialResults.getFSize()));
                    //规格型号
                    materialdo.setSpecification(materialResults.getModel());
                    if(localUnitMap.get(materialResults.getUnitName())==null)
                    {
                        return R.error(materialResults.getUnitName()+"计量单位不存在");
                    }
                    else
                    {
                        //单位ID
                        materialdo.setUnitUom(localUnitMap.get(materialResults.getUnitName()));
                    }
                    if(localMaterielTypeMap.get(materialResults.getTypeName())==null)
                    {
                        return R.error(materialResults.getTypeName()+"物料类型不存在");
                    }
                    else
                    {
                        //物料分组
                        materialdo.setType(localMaterielTypeMap.get(materialResults.getTypeName()));
                    }
                    //物料属性
                    if(localAttributeMap.get(materialResults.getErpcls())==null)
                    {
                        return R.error(materialResults.getErpcls()+"物料属性不存在");
                    }
                    else
                    {
                        //物料分组
                        materialdo.setAttribute(localAttributeMap.get(materialResults.getErpcls()));
                    }

                    materialdo.setDefaultFacility(materialResults.getStockId());
                    materialdo.setDefaultLocation(materialResults.getStockPlaceId());
                }
                materielService.batchUpdate(materielDOListUpdate);
                log.info("批量更新");
            }
            if(remoteIdList.size()>0)
            {
                //批量插入
                List<K3MaterialResultsVo> materialResultsList = materialResultsVoList.stream().filter(e -> remoteIdList.contains(e.getId())).collect(Collectors.toList());
                List<MaterielDO> materielDOListInsert= Lists.newArrayList();

                for (K3MaterialResultsVo materialResults:materialResultsList
                ) {
                    MaterielDO materieldo=new MaterielDO();
                    materieldo.setId(materialResults.getId());
                    //物料名称
                    materieldo.setName(materialResults.getName());
                    //物料代码
                    materieldo.setSerialNo(materialResults.getNumber());

                    //体积
                    materieldo.setVolume(BigDecimal.valueOf(materialResults.getFSize()));
                    //规格型号
                    materieldo.setSpecification(materialResults.getModel());
                    if(localUnitMap.get(materialResults.getUnitName())==null)
                    {
                        return R.error(materialResults.getUnitName()+"计量单位不存在");
                    }
                    else
                    {
                        //单位ID
                        materieldo.setUnitUom(localUnitMap.get(materialResults.getUnitName()));
                    }
                    if(localMaterielTypeMap.get(materialResults.getTypeName())==null)
                    {
                        return R.error(materialResults.getTypeName()+"物料类型不存在");
                    }
                    else
                    {
                        //物料分组
                        materieldo.setType(localMaterielTypeMap.get(materialResults.getTypeName()));
                    }
                    //物料属性
                    if(localAttributeMap.get(materialResults.getErpcls())==null)
                    {
                        return R.error(materialResults.getErpcls()+"物料属性不存在");
                    }
                    else
                    {
                        //物料分组
                        materieldo.setAttribute(localAttributeMap.get(materialResults.getErpcls()));
                    }
                    materieldo.setDefaultFacility(materialResults.getStockId());
                    materieldo.setDefaultLocation(materialResults.getStockPlaceId());
                    materieldo.setNetWeight(new BigDecimal(materialResults.getWeight()));
                    materieldo.setAuditSign(okAudit);
                    materieldo.setAuditor(userId);
                    materieldo.setDelFlag(0);
                    materieldo.setUseStatus(1);
                    materielDOListInsert.add(materieldo);
                }
                materielService.batchSave(materielDOListInsert);
                log.info("批量新增");
            }
        }
        return R.ok();
    }
    private void handle(List<K3MaterialResultsVo> remoteData, List<DictionaryDO> localAttributeList, List<DictionaryDO> localUnitList, List<MaterielTypeDO> localMaterielTypeDOS) {
        List<String> localMaterielTypeNameList = localMaterielTypeDOS.stream().map(MaterielTypeDO::getName).collect(Collectors.toList());
        List<String> localAttributeNameList = localAttributeList.stream().map(DictionaryDO::getName).collect(Collectors.toList());
        List<String> localUnitNameList = localUnitList.stream().map(DictionaryDO::getName).collect(Collectors.toList());

        // 获取远端所有的物料属性、单位、物料类型
        List<String> remoteAttributeNameList = remoteData.stream().map(K3MaterialResultsVo::getErpcls).distinct().collect(Collectors.toList());
        List<String> remoteUnitNameList = remoteData.stream().map(K3MaterialResultsVo::getUnitName).distinct().collect(Collectors.toList());
        List<String> remoteMaterielTypeNameList = remoteData.stream().map(K3MaterialResultsVo::getTypeName).distinct().collect(Collectors.toList());

        List<DictionaryDO> saveAttributeList = Lists.newArrayList();
        List<DictionaryDO> saveUnitList = Lists.newArrayList();
        List<MaterielTypeDO> saveMaterielTypeList = Lists.newArrayList();

        remoteAttributeNameList.removeAll(localAttributeNameList);
        remoteUnitNameList.removeAll(localUnitNameList);
        remoteMaterielTypeNameList.removeAll(localMaterielTypeNameList);
        if (remoteAttributeNameList.size() > 0) {
            DictionaryDO dictDO;
            for (String s : remoteAttributeNameList) {
                dictDO = new DictionaryDO();
                dictDO.setName(s);
                dictDO.setTypeId(MATERIEL_TYPE_ID);

                saveAttributeList.add(dictDO);
            }
        }
        if (remoteUnitNameList.size() > 0) {
            DictionaryDO dictDO;
            for (String s : remoteUnitNameList) {
                dictDO = new DictionaryDO();
                dictDO.setName(s);
                dictDO.setTypeId(UNIT_TYPE_ID);

                saveUnitList.add(dictDO);
            }
        }
        if (remoteMaterielTypeNameList.size() > 0) {
            MaterielTypeDO materielTypeDO;
            for (String s : remoteMaterielTypeNameList) {
                materielTypeDO = new MaterielTypeDO();
                materielTypeDO.setName(s);
                materielTypeDO.setIsSystem(0);

                saveMaterielTypeList.add(materielTypeDO);
            }
        }
        if (saveAttributeList.size() > 0) {
            // 批量保存
            dictionaryDao.batchSave(saveAttributeList);
            localAttributeList.addAll(saveAttributeList);
        }
        if (saveUnitList.size() > 0) {
            // 批量保存
            dictionaryDao.batchSave(saveUnitList);
            localUnitList.addAll(saveUnitList);
        }
        if (saveMaterielTypeList.size() > 0) {
            // 批量保存
            materielTypeDao.batchSave(saveMaterielTypeList);
            localMaterielTypeDOS.addAll(saveMaterielTypeList);
        }
    }
}
